package com.datasecops.scannerservices.watermark;

import com.datasecops.scannerservices.configurationfiles.WatermarkingConfiguration;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.io.IOException;
import java.io.*;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Calendar;
import java.util.Properties;

/**数据库水印的导入导出
 * mysql使用
 * @author: GeXiaoLong
 * @time: 2023/1/3 14:36
 */
@Service
@Slf4j
public class MysqlDB {

    @Resource
    private  JNILinuxSo jniLinuxSo;
    @Resource
    private Configuration configuration;


//    @Resource
//    private  configuration configuration;


//    @Resource
//    private  JNIWinSo jniWinSo;

//    @Resource
//    private WatermarkingConfiguration watermarkingConfiguration;

    // 实现数据库的导出
    public static void exportSql(WatermarkingConfiguration watermarkingConfiguration) throws IOException {
//        Properties properties = new Properties();
        //  读取属性文件
        // properties.load(Import.class.getClassLoader().getResourceAsStream("jdbc.properties"));

        Runtime runtime = Runtime.getRuntime();
        String command = getExportCommand(watermarkingConfiguration);
        System.out.println(command);
        //  这里其实是在命令窗口中执行的 command 命令行
        Process exec = runtime.exec(command);
        try {
            int i = exec.waitFor();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

    }
    // 实现数据库的导入
    public static void  importSql()  {
        try {
            Properties properties = new Properties();
            //  读取属性文件
            //properties.load(Import.class.getClassLoader().getResourceAsStream("jdbc.properties"));

            Runtime runtime = Runtime.getRuntime();
            //把所执行的命令将以字符串数组的形式出现
            String cmdarray[] = getImportCommand(properties);//根据属性文件的配置获取数据库导入所需的命令，组成一个数组
            Process process = runtime.exec(cmdarray[0]);


            //执行了第一条命令以后已经登录到mysql了，所以之后就是利用mysql的命令窗口
            OutputStream os = process.getOutputStream();
            OutputStreamWriter writer = new OutputStreamWriter(os);
            //命令1和命令2要放在一起执行
            // 这里会执行后面的代码， 将命令输出到mysql的命令窗口，进行执行
            writer.write(cmdarray[1] + "\n" + cmdarray[2]);
            writer.flush();
            writer.close();
            os.close();


        } catch (Exception e) {
            log.error("数据库执行错误 ",e);
        }
    }

    //  得到 导出数据 的 命令行语句
    private static String getExportCommand(WatermarkingConfiguration watermarkingConfiguration) {

//        StringBuffer command = new StringBuffer();
//        String username = properties.getProperty("jdbc.username");//用户名
//        String password = properties.getProperty("jdbc.password");//用户密码
//        String exportDatabaseName = properties.getProperty("jdbc.exportDatabaseName");//需要导出的数据库名
//        String host = properties.getProperty("jdbc.host");//从哪个主机导出数据库，如果没有指定这个值，则默认取localhost
//        String port = properties.getProperty("jdbc.port");//使用的端口号
//        String exportPath = properties.getProperty("jdbc.exportPath");//导出路径
//        String MysqlPath = properties.getProperty("MysqlPath"); //  路径是mysql中 bin 文件 的位置

        StringBuffer command = new StringBuffer();
        String username = watermarkingConfiguration.getUSER() ;//用户名
        String password = watermarkingConfiguration.getPASSWORD();//用户密码
        String exportDatabaseName = watermarkingConfiguration.getDBNAME();//需要导出的数据库名
        String embedTableName = watermarkingConfiguration.getEMBEDTABLENAME();
        String host = watermarkingConfiguration.getHOST();//从哪个主机导出数据库，如果没有指定这个值，则默认取localhost
        String port = watermarkingConfiguration.getPORT();//使用的端口号
//        String username = "root" ;//用户名
//        String password = "sc.9102";//用户密码
//        String exportDatabaseName = "dsm";//需要导出的数据库名
//        String embedTableName = "dlp_datarisksit_assessment_question_bank";
//        String host = "10.26.18.61";//从哪个主机导出数据库，如果没有指定这个值，则默认取localhost
//        String port = "3306";//使用的端口号
//        String exportPath = "C:\\text\\user.sql";//导出路径
//        String MysqlPath = "E:\\mysql\\bin\\"; //  路径是mysql中 bin 文件 的位置
        String exportPath = "/user/user.sql";//导出路径
        String MysqlPath = "/usr/bin/"; //  路径是mysql中 bin 文件 的位置

        //注意哪些地方要空格，哪些不要空格
//        command.append(MysqlPath).append("mysqldump -u").append(username).append(" -p").append(password)//密码是用的小p，而端口是用的大P。
//                .append(" -h").append(host).append(" -P").append(port).append(" ").append(exportDatabaseName).append(" ").append(embedTableName).append(" -r ").append(exportPath);
        command.append(MysqlPath).append("mysqldump -u").append(username).append(" -p").append(password)//密码是用的小p，而端口是用的大P。
                .append(" -h").append(host).append(" -P").append(port).append(" ").append(exportDatabaseName).append(" ").append(embedTableName).append(" -r ").append(exportPath);

//        command.append(MysqlPath).append("mysqldump -u").append(username).append(" -p").append(password)//密码是用的小p，而端口是用的大P。
//                .append(" -h").append(host).append(" -P").append(port).append(" ").append(exportDatabaseName).append(" -r ").append(exportPath);


        return command.toString();
    }

    // 得到 导入 数据库的命令
    //  得到 导入数据 的 命令行语句
    private static String[] getImportCommand(Properties properties) {

//        String username = properties.getProperty("jdbc.username");//用户名
//        String password = properties.getProperty("jdbc.password");//密码
//        String host = properties.getProperty("jdbc.host");//导入的目标数据库所在的主机
//        String port = properties.getProperty("jdbc.port");//使用的端口号
//        String importDatabaseName = properties.getProperty("dsm");//导入的目标数据库的名称
//        String importPath = properties.getProperty("jdbc.importPath");//导入的目标文件所在的位置
//        String MysqlPath = properties.getProperty("MysqlPath"); //  路径是mysql中 bin 文件 的位置

        String username = "root";//用户名
        String password = "Wzx.1104";//密码
        String host = "10.26.18.58";//导入的目标数据库所在的主机
        String port = "3306";//使用的端口号
        String importDatabaseName = "WatermarkingDatabase";//导入的目标数据库的名称
//        String importPath = "C:\\text\\user.sql";//导入的目标文件所在的位置
//        String MysqlPath = "E:\\mysql\\bin\\"; //  路径是mysql中 bin 文件 的位置
        String importPath = "/user/user.sql";//导入的目标文件所在的位置
        String MysqlPath = "/usr/bin/"; //  路径是mysql中 bin 文件 的位置

        if (new File(importPath).exists()){
            log.error("有文件");
        }else{
            log.error("没有文件");
        }

        //第一步，获取登录命令语句
        String loginCommand = new StringBuffer().append(MysqlPath).append("mysql -h").append(host).append(" -u").append(username).append(" -p").append(password)
                .append(" -P").append(port).toString();
        //第二步，获取切换数据库到目标数据库的命令语句
        String switchCommand = new StringBuffer().append("use ").append(importDatabaseName).toString();
        //第三步，获取导入的命令语句
        String importCommand = new StringBuffer(" source ").append(importPath).toString();
        //需要返回的命令语句数组

        String[] commands = new String[] {loginCommand, switchCommand, importCommand};
        log.error("数据库的导入语句1:   "+loginCommand);
        log.error("数据库的导入语句2:   "+switchCommand);
        log.error("数据库的导入语句3:   "+importCommand);
        log.error("数据库的导入是否正确:   "+commands);
        return commands;

    }


    // 实现水印加注后数据库的导出
    public static void exportWatermarkSql(WatermarkingConfiguration watermarkingConfiguration) throws IOException {
        log.error("数据库安装程序运行进来了吗3?");
//        Properties properties = new Properties();
        //  读取属性文件
        // properties.load(Import.class.getClassLoader().getResourceAsStream("jdbc.properties"));

        Runtime runtime = Runtime.getRuntime();
        String command = getExportCommandWatermark(watermarkingConfiguration);
        System.out.println(command);
        //  这里其实是在命令窗口中执行的 command 命令行
        runtime.exec(command);
    }
    //  得到 水印加注后 导出数据 的 命令行语句
    private static String getExportCommandWatermark(WatermarkingConfiguration watermarkingConfiguration) {

        StringBuffer command = new StringBuffer();
        String username ="root";//用户名
        String password = "Wzx.1104";//用户密码
        String exportDatabaseName = "WatermarkingDatabase";//需要导出的数据库名
        String embedTableName = watermarkingConfiguration.getEMBEDTABLENAME();
        String host = "10.26.18.58";//从哪个主机导出数据库，如果没有指定这个值，则默认取localhost
        String port = "3306";//使用的端口号
        String exportPath = "/user/client.sql";//导出路径
        String MysqlPath = "/usr/bin/"; //  路径是mysql中 bin 文件 的位置
        command.append(MysqlPath).append("mysqldump -u").append(username).append(" -p").append(password)//密码是用的小p，而端口是用的大P。
                .append(" -h").append(host).append(" -P").append(port).append(" ").append(exportDatabaseName).append(" ").append(embedTableName).append(" -r ").append(exportPath);


        return command.toString();
    }

    // 实现水印加注后数据库的导入
    public static void importWatermarkSql(WatermarkingConfiguration watermarkingConfiguration) throws IOException {
        log.error("数据库安装程序运行进来了吗4?");
        Properties properties = new Properties();
        //  读取属性文件
        //properties.load(Import.class.getClassLoader().getResourceAsStream("jdbc.properties"));

        Runtime runtime = Runtime.getRuntime();
        //把所执行的命令将以字符串数组的形式出现
        String cmdarray[] = getImportCommandWatermark(watermarkingConfiguration);//根据属性文件的配置获取数据库导入所需的命令，组成一个数组
        Process process = runtime.exec(cmdarray[0]);

        //执行了第一条命令以后已经登录到mysql了，所以之后就是利用mysql的命令窗口

        java.io.OutputStream os = process.getOutputStream();
        OutputStreamWriter writer = new OutputStreamWriter(os);
        //命令1和命令2要放在一起执行
        // 这里会执行后面的代码， 将命令输出到mysql的命令窗口，进行执行
        writer.write(cmdarray[1] + "\n" + cmdarray[2]);
        writer.flush();
        writer.close();
        os.close();
    }

    // 得到 导入 数据库的命令  加注水印后
    //  得到 导入数据 的 命令行语句
    private static String[] getImportCommandWatermark(WatermarkingConfiguration watermarkingConfiguration) {


        String username = watermarkingConfiguration.getUSER();//用户名
        String password = watermarkingConfiguration.getPASSWORD();//密码
        String host = watermarkingConfiguration.getHOST();//导入的目标数据库所在的主机
        String port = watermarkingConfiguration.getPORT();//使用的端口号
        String importDatabaseName = "text";//导入的目标数据库的名称//这里后期要换成动态的
        String importPath = "/user/client.sql";//导入的目标文件所在的位置
        String MysqlPath = "/usr/bin/"; //  路径是mysql中 bin 文件 的位置

        //第一步，获取登录命令语句
        String loginCommand = new StringBuffer().append(MysqlPath).append("mysql -h").append(host).append(" -u").append(username).append(" -p").append(password)
                .append(" -P").append(port).toString();
        //第二步，获取切换数据库到目标数据库的命令语句
        String switchCommand = new StringBuffer().append("use ").append(importDatabaseName).toString();
        //第三步，获取导入的命令语句
        String importCommand = new StringBuffer(" source ").append(importPath).toString();
        //需要返回的命令语句数组

        String[] commands = new String[] {loginCommand, switchCommand, importCommand};

        return commands;
    }


//     /**
//      *复制sql文件名
//      * @Description
//      * @author GeXiaoLong
//      * @time 2023/1/11 17:00
//      * @param
//      * @return
//      */
//    @SneakyThrows
//    public static void copy()  {
//        String url1 = "/user/user.sql";// 源文件路径
//        String url2 = "/user/users.sql";// 目标路径（复制到E盘，重命名为b.txt）
////        String url1 = "P:\\text\\userb.sql";// 源文件路径
////        String url2 = "P:\\text\\user.sql";// 目标路径（复制到E盘，重命名为b.txt）
//        FileInputStream in = new FileInputStream(new File(url1));
//        FileOutputStream out = new FileOutputStream(new File(url2));
//        byte[] buff = new byte[512];
//        int n = 0;
//        System.out.println("复制文件：" + "\n" + "源路径：" + url1 + "\n" + "目标路径："
//                + url2);
//        while ((n = in.read(buff)) != -1) {
//            out.write(buff, 0, n);
//        }
//        out.flush();
//        in.close();
//        out.close();
//        System.out.println("复制完成");
//    }



//    /**
//     *复制sql文件名
//     * @Description
//     * @author GeXiaoLong
//     * @time 2023/1/11 17:00
//     * @param
//     * @return
//     */
//    @SneakyThrows
//    public static void copying()  {
//        String url1 = "/user/client.sql";// 源文件路径
//        String url2 = "/user/clients.sql";// 目标路径（复制到E盘，重命名为b.txt）
//        FileInputStream in = new FileInputStream(new File(url1));
//        FileOutputStream out = new FileOutputStream(new File(url2));
//        byte[] buff = new byte[512];
//        int n = 0;
//        System.out.println("复制文件：" + "\n" + "源路径：" + url1 + "\n" + "目标路径："
//                + url2);
//        while ((n = in.read(buff)) != -1) {
//            out.write(buff, 0, n);
//        }
//        out.flush();
//        in.close();
//        out.close();
//        System.out.println("复制完成");
//    }



    public  Integer text(String tableName) throws IOException, SQLException {
        WatermarkingConfiguration watermarkingConfiguration = new WatermarkingConfiguration();
        watermarkingConfiguration.setHOST("10.26.18.61");
        watermarkingConfiguration.setPORT("3306");
        watermarkingConfiguration.setUSER("root");
        watermarkingConfiguration.setPASSWORD("sc.9102");
//        String DbName = "dsm";
        String OperType = "OtEmbed";
        String EmbedRableNAme = tableName;

        //换到嵌入库
        String dbname = "WatermarkingDatabase";
        String dbName = watermarkingConfiguration.getDbName()+dbname;
        watermarkingConfiguration.setDbName(dbName);

        String WmType = "WmFakeRow";
        String TraceWmEmbedChars = "DSO Database IPR, 2022.11.11, China Beijing. To:China Mobile. Usage:Collaboration, Validity:2200.12.31.";
        watermarkingConfiguration.setDBNAME("soul");
        watermarkingConfiguration.setEMBEDTABLENAME(EmbedRableNAme);
//        String dbName = watermarkingConfiguration.getDbName()+DbName;
//        watermarkingConfiguration.setDbName(dbName);
        String operType = watermarkingConfiguration.getOperType()+OperType;
        watermarkingConfiguration.setOperType(operType);
        if ("OtEmbed".equalsIgnoreCase(OperType)){
            String embedTableName = watermarkingConfiguration.getEmbedTableName()+EmbedRableNAme;
            watermarkingConfiguration.setEmbedTableName(embedTableName);
            String extractWmFileNameName = watermarkingConfiguration.getEmbedWmFileName()+EmbedRableNAme+".txt";
            watermarkingConfiguration.setEmbedWmFileName(extractWmFileNameName);
            String extractAuxInfoFileName = watermarkingConfiguration.getEmbedAuxInfoFileName()+EmbedRableNAme+".txt";
            watermarkingConfiguration.setEmbedAuxInfoFileName(extractAuxInfoFileName);
        }
        String runOutFileName = watermarkingConfiguration.getRunOutFileName()+EmbedRableNAme+".log";
        watermarkingConfiguration.setRunOutFileName(runOutFileName);
        String tableDesFileName = watermarkingConfiguration.getTableDesFileName()+EmbedRableNAme+".txt";
        watermarkingConfiguration.setTableDesFileName(tableDesFileName);
        String wmType = watermarkingConfiguration.getWmType()+WmType;
        watermarkingConfiguration.setWmType(wmType);
        String traceWmEmbedChars = watermarkingConfiguration.getTraceWmEmbedChars()+TraceWmEmbedChars;
        watermarkingConfiguration.setTraceWmEmbedChars(traceWmEmbedChars);

        configuration.diskDropFile(watermarkingConfiguration);
        watermarkingDatabase();
        exportSql(watermarkingConfiguration);
        //copy();
        try {
            Thread.sleep(2000);
        } catch (Exception e) {
            log.error("出错了",e);
        }
        importSql();
        try {
            Thread.sleep(2000);
        } catch (Exception e) {
            log.error("出错了2",e);
        }
        Integer text = jniLinuxSo.text();
        completeWatermarking(watermarkingConfiguration);
        exportWatermarkSql(watermarkingConfiguration);
        //copying();
        try {
            Thread.sleep(2000);
        } catch (Exception e) {
            log.error("出错了3",e);
        }
        importWatermarkSql(watermarkingConfiguration);

        return text;
    }

    /**
     *导回源库是创建一个新数据库
     * @Description
     * @author GeXiaoLong
     * @time 2023/2/13 11:43
     * @param
     * @return
     */
    public  void completeWatermarking(WatermarkingConfiguration watermarkingConfiguration) throws SQLException {
        Statement st = null;
        try {
            log.error("数据库安装程序运行进来了吗2?");
            Class.forName("com.mysql.jdbc.Driver");
            String url = "jdbc:mysql://" +watermarkingConfiguration.getHOST()+":"+watermarkingConfiguration.getPORT()+"/mysql?useUnicode=true&characterEncoding=UTF8&useSSL=false&serverTimezone=Asia/Shanghai";
            String username = watermarkingConfiguration.getUSER();
            String password = watermarkingConfiguration.getPASSWORD();
            Connection c = DriverManager.getConnection(url, username, password);
            st = c.createStatement();
            //int i = st.executeUpdate("create table test(id int,name varchar (80))");
            //rs = st.executeQuery("select * from student");
            st.executeUpdate("CREATE DATABASE IF NOT EXISTS text");//创建数据库
        } catch (ClassNotFoundException | SQLException e) {
            e.printStackTrace();
            log.error("数据库添加程序运行失败,原因是:    "+e.getMessage());
        } finally {
            st.close();
        }

    }


    /**
     *在目标库创建数据库
     * @Description
     * @author GeXiaoLong
     * @time 2023/2/13 11:46
     * @param
     * @return
     */
    public  void watermarkingDatabase() throws SQLException {
        log.error("数据库安装程序进来了吗?");
        Statement st = null;
        try {
            log.error("数据库安装程序运行进来了吗?");
            Class.forName("com.mysql.jdbc.Driver");
            String url = "jdbc:mysql://10.26.18.58:3306/mysql?useUnicode=true&characterEncoding=UTF8&useSSL=false&serverTimezone=Asia/Shanghai";
            String username = "root";
            String password = "Wzx.1104";
            Connection c = DriverManager.getConnection(url, username, password);
            st = c.createStatement();
            //int i = st.executeUpdate("create table test(id int,name varchar (80))");
            //rs = st.executeQuery("select * from student");

//            st.executeUpdate("create schema WatermarkingDatabase");//创建数据库
            st.executeUpdate("CREATE DATABASE IF NOT EXISTS WatermarkingDatabase");//创建数据库,有就跳过,没有就创建

        } catch (Exception e) {
            log.error("数据库添加程序运行失败,原因是: ",e);
        } finally {
            st.close();
        }
    }


    public static void main(String[] args) throws IOException, SQLException {
        //JNILinuxSo.main();
        //JNIWinSo.text();
        // jniWinSo.text();
        //copy();
        WatermarkingConfiguration configuration = new WatermarkingConfiguration();
        exportSql(configuration);
        importSql();
        MysqlDB importAndExports = new MysqlDB();
        //importAndExports.text(tableName);

        Calendar calendar = Calendar.getInstance();
        long time = calendar.getTimeInMillis();
        System.out.println(time);
        //exportSql(watermarkingConfiguration);
        //importSql();
        Calendar calendars = Calendar.getInstance();
        long times = calendars.getTimeInMillis();
        System.out.println(times);
        System.out.println((times-time)/1000);
    }


}
